// token
import { isObject } from '@vueuse/core'
import { clone, isArray, isString } from 'xe-utils'
import { defaultCol, formatValues, getFormatValues, setFormComponents } from '@/utils/custom'
import type { BusinessUIFormType, BusinessUIQueryType, BusinessUITableType } from '@/types/custom'
import { ElMessage } from 'element-plus'

export const TokenKey = 'Authorization'

export const adminKey = 'admin'

// 按钮权限标识
export const AuthTypes = ['btn.add', 'btn.del', 'btn.edit', 'btn.link']

// 开发环境
export const isDevelopment = import.meta.env.MODE === 'development'

// 龙江工业ID
// export const crmOrgId = '12230101'

// /**
//  * 补零 如：1 => 01
//  * @param num 被操作数
//  * @param n 固定的总位数
//  */
// export const prefixZero = (num: number, n: number) => {
//   return (Array(n).join(String(0)) + num).slice(-n)
// }

/**
 * 初始化菜单的默认模板
 * @param routes
 */
export const getMenuDefaultComponent = (routes: RouteItems) => {
  routes.map((route: RouteItem) => {
    if (route.meta?.isLink) {
      if (route.meta?.isIframe) {
        // 内嵌iframes模板
        route.component = '/layout/routerView/iframes'
      } else {
        // 外链模板
        route.component = '/layout/routerView/link'
      }
    } else if (!route.component) {
      // 默认模板
      route.component = '/default/defaultIndex'
    }
    if (route.children) getMenuDefaultComponent(route.children)
  })
}

/**
 * 复制文字
 * @param {String} text
 * @return {Promise<never>|Promise<void>}
 */
export const copyText = (text: string): Promise<void> => {
  if (navigator && navigator.clipboard) {
    return navigator.clipboard.writeText(text)
  } else {
    return Promise.reject()
  }
}

/**
 * 粘贴文字
 * @return {Promise<string>}
 */
export const pasteText = (): Promise<string> => {
  if (navigator && navigator.clipboard) {
    return navigator.clipboard.readText()
  } else {
    return Promise.reject()
  }
}

/**
 * 默认值转String
 * @param option
 * @param key
 */
export const defaultValueToString = (option: TypedAny, key: string) => {
  if (!option && !isObject(option)) return
  const parse_key = `${key}_parse`
  const data = option[parse_key]
  if (isObject(data)) {
    option[key] = JSON.stringify(data)
  } else {
    option[key] = ''
  }
}

/**
 * 默认值转JSON
 * @param option
 * @param key
 * @param isFormatValue // 是否提前格式化default_value里面的__me__等等关键字
 */
export const defaultValueToJson = (option: TypedAny, key: string, isFormatValue?: boolean) => {
  if (!key || !option || !isObject(option)) return
  const parse_key = `${key}_parse`
  const data = option[key] || '{}'
  let parseJson: any = {}
  try {
    if (isString(data)) {
      parseJson = JSON.parse(data)
    }
  } catch (e) {
    console.log(data, ' => ', '错误')
  }
  if (isFormatValue && key === 'default_value') {
    for (const k in parseJson) {
      const value = parseJson[k]

      if (isArray(value) && formatValues.some(s => value.includes(s.value))) {
        parseJson[k] = value.map((v) => getFormatValues(v, v))
      } else if (formatValues.some((s) => s.value === value)) {
        parseJson[k] = getFormatValues(value)
      }
    }
  }
  option[parse_key] = parseJson
}

/**
 * 默认JSON
 * @param option
 * @param isFormatValue // 是否提前格式化default_value里面的__me__等等关键字
 */
export const defaultFormValueToJson = (
  option: BusinessUIFormType | BusinessUIQueryType | BusinessUITableType | undefined,
  isFormatValue?: boolean
) => {
  if (option) {
    defaultValueToJson(option, 'default_value', isFormatValue)
    if ('items' in option) {
      const list = option.items || []
      // 表单需要的值
      setFormComponents(list, (item) => {
        // 默认值转JSON
        defaultValueToJson(item, 'set_json', isFormatValue)
        defaultValueToJson(item, 'default_value', isFormatValue)
        if (!item.set_json_parse.props) {
          item.set_json_parse.props = {}
        }
        if (!item.set_json_parse.col) {
          item.set_json_parse.col = clone(defaultCol, true)
        }
      })
    }
    if ('columns' in option) {
      const list = option.columns || []
      list.forEach((v) => {
        // 默认值转JSON
        defaultValueToJson(v, 'set_json', isFormatValue)
        defaultValueToJson(v, 'default_value', isFormatValue)
        if (!v.set_json_parse.props) {
          v.set_json_parse.props = {}
        }
      })
    }
    if ('children' in option) {
      const list = option.children || []
      list.forEach((v) => {
        // 默认值转JSON
        defaultValueToJson(v, 'default_value', isFormatValue)
      })
    }
  }
}

/**
 * 拼接 url 参数
 * @param baseUrl
 * @param params
 */
export const buildUrl = (baseUrl: string, params: TypedAny) => {
  const query = Object.keys(params)
    .map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
    .join('&')
  return query.length ? baseUrl + '?' + query : baseUrl
}

/**
 * @description 将金额格式化
 * @param money
 * @param options
 * @returns {string}
 * @private
 */
export const _MoneyFormat = (money: number, options?: Intl.NumberFormatOptions) => {
  if (!options) {
    options = {
      style: 'currency',
      // 输出人民币
      currency: 'CNY',
      // 输出美元，语言设置为'en'
      // currency: 'USD',
      // currencySign选项启用记帐格式
      currencySign: 'accounting',
      // 保留两位小数
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    }
  }
  return new Intl.NumberFormat('zh-CN', options).format(money)
}

/**
 * 交换位置
 * @param arr
 * @param index1
 * @param index2
 */
export function swapArrayElements(arr: any[], index1: number, index2: number) {
  arr[index1] = arr.splice(index2, 1, arr[index1])[0]
  return arr
}

/**
 * 路径转首字母大写
 * @param str
 */
export function toPathCapitalize(str: string) {
  const re = /\/(\w)/g
  return str.replace(re, function($0: any, $1: any) {
    return $1.toUpperCase()
  })
}

/**
 * 组件名称转首字母大写
 * @param str
 */
export function toNameCapitalize(str: string) {
  // 使用split方法按'-'分割字符串，得到一个数组
  let parts = str.split('-')
  // 创建一个空数组来存储转换后的部分
  let capitalizedParts: string[] = []
  // 遍历每个部分
  parts.forEach(part => {
    // 将每个部分的首字母转换为大写，其余部分转换为小写（如果需要的话）
    // 注意：如果不需要将其他部分转换为小写，可以省略.toLowerCase()
    let capitalizedPart = part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()
    // 将转换后的部分添加到新数组中
    capitalizedParts.push(capitalizedPart)
  })
  // 使用join方法将数组中的部分重新组合成一个字符串
  return capitalizedParts.join('')
}

/**
 * @param {date} time 订单时间（日期格式或者时间戳）
 * @param {number} num 返回几个时间单位，如：1周(num=1)，1周2天(num=2),1周2天1小时(num=3)
 */
export function toFormatTime(time: string, num = 1) {
  const timeArr = [
    365 * 24 * 60 * 60 * 1000,
    30 * 24 * 60 * 60 * 1000,
    7 * 24 * 60 * 60 * 1000,
    24 * 60 * 60 * 1000,
    60 * 60 * 1000,
    60 * 1000,
    1000
  ]
  const unit = ['年', '个月', '周', '天', '小时', '分钟', '秒钟']
  let timeDiff = Date.now() - new Date(time).getTime()
  if (timeDiff <= 0) return '刚刚'
  const tip = []
  for (let i = 0; i < timeArr.length; i++) {
    if (timeDiff < timeArr[i]) continue

    const temp = Math.floor(timeDiff / timeArr[i])
    timeDiff = timeDiff % timeArr[i]

    if (temp > 0) {
      tip.push(temp + unit[i])
    }

    if (tip.length >= num) break
  }
  return tip.join('') + '前'
}

// /**
//  * 树形图排序
//  * @param arr
//  * @param field
//  * @param order desc降序 asc升序
//  */
// export const toTreeSort = (arr: TypedAny[], field: string, order?: string | null) => {
//   eachTree(arr, (item) => {
//     if (item.children && item.children.length) {
//       item.children = toArraySort(item.children, field, order)
//     }
//   })
//   return toArraySort(arr, field, order)
// }
//
// /**
//  * @description 随机数（闭区间）
//  * @param num
//  */
// export const randomNum = (num: number) => Math.floor(Math.random() * (num + 1))

// /**
//  * 数组排序
//  * @param arr
//  * @param field
//  * @param order desc降序 asc升序
//  */
// export const toArraySort = (arr: TypedAny[], field: string, order?: string | null) => {
//   return arr.sort((a: TypedAny, b: TypedAny) => {
//     if (isNumber(a[field]) || isBoolean(a[field])) {
//       if (order === 'asc') {
//         // @ts-ignore
//         return a[field] - b[field]
//       } else {
//         // @ts-ignore
//         return b[field] - a[field]
//       }
//     }
//     const numA = Number(a[field].replace(/\D/g, ''))
//     const numB = Number(b[field].replace(/\D/g, ''))
//     // 如果都是纯数字，则直接比较数值大小
//     if (!isNaN(numA) && !isNaN(numB)) {
//       if (order === 'asc') {
//         return numA - numB
//       } else {
//         return numB - numA
//       }
//     }
//     return a[field].localeCompare(b)
//   })
// }

/**
 * 显示浏览器
 * @param url
 * @param windowName
 */
export const openUniqueWindow = (url: string, windowName: string) => {
  // 检查窗口是否已经打开
  const win: Window | null = window.open('', windowName)
  if (win === null || win.closed) {
    // 如果窗口已经打开，则重新使用它
    window.open(url, windowName)
  } else {
    // 如果窗口未打开，先设置URL
    win.location.href = url
  }
  win?.focus()
}

/**
 * 数组交换位置
 * @param arr
 * @param indexA
 * @param indexB
 */
export const swapArray = (arr: any[], indexA: number, indexB: number) => {
  const temp = arr[indexA]
  arr[indexA] = arr[indexB]
  arr[indexB] = temp
}

// /**
//  * @param {Object} currentValue
//  * @param {Object} lastYearValue
//  * @description 求百分比 currentValue：当前数据，lastYearValue：对比数据
//  */
// export const toPercent = (currentValue: number, lastYearValue: number) => {
//   if (currentValue === 0) {
//     return 100
//   } else if (lastYearValue === 0) {
//     return 0
//   }
//   // 计算同比增长率
//   const percent = (currentValue - lastYearValue) / lastYearValue
//   return parseFloat((percent * 100).toFixed(2))
// }

// /**
//  * @description 切换箱 万支 箱 万箱
//  * @param {Number} num
//  * @param {Number} type 0 万支 1 箱 2 万箱
//  */
// export const getUnit = (num: number, type: number) => {
//   const n = num || 0
//   if (type === 1) {
//     return Math.round(n / 5)
//   } else if (type === 2) {
//     return parseFloat((n / 5 / 10000).toFixed(2))
//   } else {
//     return Math.round(n)
//   }
// }
//
// /**
//  * @description 切换箱 元 万元
//  * @param {Number} num
//  * @param {Number} type 1 元 2 万元
//  * @param float true 自适应保留两位小数， false 强制保留两位小数包括00.00
//  */
// export const getMoney = (num: number, type: number, float?: boolean) => {
//   const n = num || 0
//   let amount
//   if (type === 2) {
//     amount = (n / 10000).toFixed(2)
//   } else {
//     amount = n.toFixed(2)
//   }
//   return float ? parseFloat(amount) : Number(amount)
// }

// /**
//  * 获取增幅颜色class
//  * @param num
//  */
// export const getIncreaseClass = (num?: number) => {
//   const amount = Number(num) || 0
//   if (amount > 0) return 'color-danger'
//   else if (amount < 0) return 'color-success'
//   else return 'color-info'
// }
//
// /**
//  * 判断数值正负给予颜色className
//  * @param {number} amount 数值
//  */
// export function getIncreaseColor(amount: number) {
//   const num = parseFloat(String(amount || 0))
//   return num === 0 ? '' : num < 0 ? 'color-success' : 'color-danger'
// }

/**
 * 最近访问去重
 * @param {Object} arr 数组
 * @param {String} key key
 */
export function unique(arr: TypedAny[], key = 'path') {
  if (!arr.length) return []
  const newArr = [arr[0]]
  for (let i = 1; i < arr.length; i++) {
    let repeat = false
    for (let j = 0; j < newArr.length; j++) {
      if (arr[i][key] === newArr[j][key]) {
        repeat = true
        break
      }
    }
    if (!repeat) {
      newArr.push(arr[i])
    }
  }
  return newArr
}

/**
 * 秒转时分秒
 * @param seconds
 */
export const formatTrackTime = (seconds: number) => {
  const minutes = Math.floor((seconds % 3600) / 60)
  const remainingSeconds = Math.floor(seconds % 60)
  const m = minutes.toString().padStart(2, '0')
  const s = remainingSeconds.toString().padStart(2, '0')
  return `${m}:${s}`
}

/**
 * 数字金额转换成中文大写数字的函数（可处理负值）
 * @param money
 * @param type 大写中文
 * @return {string}
 */
export function intToMoney(money: number | string, type = true) {
  let n
  let i
  let cnNums = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'] //汉字的数字
  let cnIntUnit = ['', '十', '百', '千'] //基本单位
  const cnIntUnits = ['', '万', '亿', '兆'] //对应整数部分扩展单位
  const cnDecUnits = ['角', '分', '毫', '厘'] //对应小数部分单位
  const cnInteger = '整' //整数金额时后面跟的字符
  const cnIntLast = '元' //整型完以后的单位
  const maxNum = 999999999999999.9999 //最大处理的数字
  let IntegerNum //金额整数部分
  let DecimalNum //金额小数部分
  let ChineseStr = '' //输出的中文金额字符串
  let parts //分离金额后用的数组，预定义
  let Symbol = '' //正负值标记
  // 大写
  if (type) {
    cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
    cnIntUnit = ['', '拾', '佰', '仟']
  }
  if (money === '') return ''
  money = parseFloat(String(money))
  if (money >= maxNum) {
    alert('超出最大处理数字')
    return ''
  }
  if (money === 0) {
    ChineseStr = cnNums[0] + cnIntLast + cnInteger
    return ChineseStr
  }
  if (money < 0) {
    money = -money
    Symbol = '负 '
  }
  money = money.toString() //转换为字符串
  if (money.indexOf('.') === -1) {
    IntegerNum = money
    DecimalNum = ''
  } else {
    parts = money.split('.')
    IntegerNum = parts[0]
    DecimalNum = parts[1].substring(0, 3)
  }
  if (parseInt(IntegerNum, 10) > 0) {
    //获取整型部分转换
    let zeroCount = 0
    const IntLen = IntegerNum.length
    for (i = 0; i < IntLen; i++) {
      n = IntegerNum.substring(i, i + 1)
      const p = IntLen - i - 1
      const q = p / 4
      const m = p % 4
      if (n === '0') {
        zeroCount++
      } else {
        if (zeroCount > 0) {
          ChineseStr += cnNums[0]
        }
        zeroCount = 0 //归零
        ChineseStr += cnNums[parseInt(n)] + cnIntUnit[m]
      }
      if (m === 0 && zeroCount < 4) {
        ChineseStr += cnIntUnits[q]
      }
    }
    ChineseStr += cnIntLast
    //整型部分处理完毕
  }
  if (DecimalNum !== '') {
    //小数部分
    const decLen = DecimalNum.length
    for (i = 0; i < decLen; i++) {
      n = DecimalNum.substring(i, i + 1)
      if (n !== '0') {
        ChineseStr += cnNums[Number(n)] + cnDecUnits[i]
      }
    }
  }
  if (ChineseStr === '') {
    ChineseStr += cnNums[0] + cnIntLast + cnInteger
  } else if (DecimalNum === '') {
    ChineseStr += cnInteger
  }
  ChineseStr = Symbol + ChineseStr

  return ChineseStr
}

// /**
//  *
//  * @param uuid 是否是UUID
//  * @returns
//  */
// export const isUUID = (uuid: string) => {
//   const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
//   return uuidPattern.test(uuid.toLowerCase())
// }

/**
 *
 * @param id 是否是表格生成的 row_{index} ID格式
 * @returns
 */
export const isGridRowId = (id: string | number) => {
  return id.toString().startsWith('row_')
}

/**
 * 一键复制字符串
 * @param text
 */
export function copyTextToClipboard(text: string) {
  if (!navigator.clipboard) {
    // 如果浏览器不支持 navigator.clipboard API
    fallbackCopyTextToClipboard(text)
    return
  }
  navigator.clipboard.writeText(text).then(function() {
    ElMessage.success('复制成功')
  }, function(text) {
    console.log(text)
    ElMessage.warning('复制失败')
  })
}

/**
 * 一键复制字符串（兼容）
 * @param text
 */
export function fallbackCopyTextToClipboard(text: string) {
  const textArea = document.createElement('textarea')
  textArea.value = text

  // 避免在屏幕上滚动到文本区域
  textArea.style.top = '0'
  textArea.style.left = '0'
  textArea.style.position = 'fixed'

  document.body.appendChild(textArea)
  textArea.focus()
  textArea.select()

  try {
    const successful = document.execCommand('copy')
    const msg = successful ? '成功' : '失败'
    ElMessage.success('复制' + msg)
  } catch (err) {
    ElMessage.warning('复制失败')
  }
  document.body.removeChild(textArea)
}

//
//
// /**
//  * 下载JSON文件
//  * @param {Object} data
//  * @param {String} filename
//  * @description 下载JSON文件
//  */
// export function saveJSON(data: any, filename?: string) {
//     if (!data) {
//         alert("detail is null");
//         return;
//     }
//     if (!filename) filename = "json.json";
//     if (typeof data === "object") {
//         data = JSON.stringify(data, undefined, 4);
//     }
//     // 创建一个新的Blob对象，并使用它创建一个链接元素
//     const blob = new Blob([data], {type: 'text/json'});
//     const url = URL.createObjectURL(blob);
//
//     // 创建一个a标签，并设置属性
//     const downloadLink = document.createElement("a");
//     downloadLink.href = url;
//     downloadLink.download = filename; // 文件名
//
//     // 触发下载
//     document.body.appendChild(downloadLink);
//     downloadLink.click();
//     document.body.removeChild(downloadLink);
// }
